package com.caoji.item.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.caoji.advice.lyExcption;
import com.caoji.constants.MQConstants;
import com.caoji.dto.PageDTO;
import com.caoji.entity.SkuDTO;
import com.caoji.entity.SpecParamDTO;
import com.caoji.entity.SpuDTO;
import com.caoji.entity.SpuDetailDTO;
import com.caoji.item.entity.*;
import com.caoji.item.mapper.SpuMapper;
import com.caoji.item.service.*;
import com.caoji.utils.JsonUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class SpuServiceImpl extends ServiceImpl<SpuMapper, Spu> implements SpuService {
    @Autowired
    BrandService brandService;
    @Autowired
    CategoryService categoryService;
    @Autowired
    SkuService skuService;

    @Autowired
    SpecParamService specParamService;

    @Autowired
    SpuDetailService spuDetailService;

    @Override
    public PageDTO<SpuDTO> querypage(Integer page, Integer rows, Boolean saleable, Long categoryId, Long brandId, Long id) {
        Page<Spu> page1 = query().eq(saleable != null, "saleable", saleable)
                .eq(categoryId != null, "cid3", categoryId)
                .eq(brandId != null, "brand_id", brandId)
                .eq(id != null, "id", id)
                .page(new Page<>(page, rows));
        List<SpuDTO> records = SpuDTO.convertEntityList(page1.getRecords());
        for (SpuDTO record : records) {
            handleCategoryAndBrandName(record);
        }
        return new PageDTO<>(page1.getTotal(), page1.getPages(), records);

    }

    @Override
    @Transactional
    public void addspu(SpuDTO spuDTO) {
        //保存spu
        Spu spu = spuDTO.toEntity(Spu.class);
        spu.setSaleable(true);
        boolean success = save(spu);
        if (!success) {
            throw new lyExcption(500, "商品新增失败");
        }
        SpuDetailDTO spuDetail = spuDTO.getSpuDetail();
        if (spuDetail == null) {
            throw new lyExcption(500, "细节不能为空");
        }
        spuDetail.setSpuId(spu.getId());
        success = spuDetailService.save(spuDetail.toEntity(SpuDetail.class));
        if (!success) {
            throw new lyExcption(500, "商品新增失败");
        }
        List<SkuDTO> skus = spuDTO.getSkus();

        if (CollectionUtils.isEmpty(skus)) {
            throw new lyExcption(400, "skus至少有一个");
        }
        List<Sku> skulist = skus.stream().map(skuDTO -> {
            Sku sku = skuDTO.toEntity(Sku.class);
            sku.setSaleable(spu.getSaleable());
            sku.setSpuId(spu.getId());
            return sku;
        }).collect(Collectors.toList());
        skuService.saveBatch(skulist);

    }

    @Override
    public SpuDTO qyeryspualls(Long id) {

        SpuDTO spuDTO = qyeryspu(id);
        SpuDetailDTO spuDetailDTO = spuDetailService.qyerydetail(id);
        spuDTO.setSpuDetail(spuDetailDTO);
        List<SkuDTO> skuDTOS = skuService.qyeryskuall(id);
        spuDTO.setSkus(skuDTOS);
        return spuDTO;
    }


    @Override
    public SpuDTO qyeryspu(Long id) {

        return new SpuDTO(getById(id));
    }

    @Autowired
    AmqpTemplate amqpTemplate;
    @Override
    @Transactional
    public void isSaleable(Long id, Boolean saleable) {
        Spu spu = getById(id);
        spu.setSaleable(saleable);
        updateById(spu);
        String routingkey = saleable?MQConstants.RoutingKeyConstants.ITEM_UP_KEY:MQConstants.RoutingKeyConstants.ITEM_DOWN_KEY;
        amqpTemplate.convertAndSend(MQConstants.ExchangeConstants.ITEM_EXCHANGE_NAME,routingkey,id);
    }

    @Override
    @Transactional
    public void updategoods(SpuDTO spuDTO) {
        Long id = spuDTO.getId();
        if (id != null) {
            Spu spu = spuDTO.toEntity(Spu.class);
            boolean success = updateById(spu);
            if (!success) {
                throw new lyExcption(500, "更新商品失败");
            }
        }

        SpuDetailDTO spuDetail = spuDTO.getSpuDetail();
        if (spuDetail != null) {
            boolean success = spuDetailService.updateById(spuDetail.toEntity(SpuDetail.class));
            if (!success) {
                throw new lyExcption(500, "更新商品失败");
            }
        }

        List<SkuDTO> skuDTOS = spuDTO.getSkus();
        if (CollectionUtils.isEmpty(skuDTOS)) {
            return;
        }
        //如果是null的话，那就相当于true，不删除
        Map<Boolean, List<Sku>> map = skuDTOS.stream().
                map(sku -> sku.toEntity(Sku.class)).
                collect(Collectors.groupingBy(sku -> sku.getSaleable() == null));
        //是要删除的
        List<Sku> skusdel = map.get(false);
        if (!CollectionUtils.isEmpty(skusdel)) {
            List<Long> longList = skusdel.stream().map(Sku::getId).collect(Collectors.toList());
            boolean success = skuService.removeByIds(longList);
            if (!success) {
                throw new lyExcption(500, "更新商品失败");
            }
        }
        //不是删除的
        List<Sku> skuList = map.get(true);
        if (!CollectionUtils.isEmpty(skuList)) {
            boolean success = skuService.saveOrUpdateBatch(skuList);
            if (!success) {
                throw new lyExcption(500, "更新商品失败");
            }
        }

    }

    private void handleCategoryAndBrandName(SpuDTO record) {
        Brand brand = brandService.getById(record.getBrandId());
        if (brand != null) {
            record.setBrandName(brand.getName());
        }
        List<Category> categories = categoryService.listByIds(record.getCategoryIds());
        if (!CollectionUtils.isEmpty(categories)) {
            String name = categories.stream().map(Category::getName).collect(Collectors.joining("/"));
            record.setCategoryName(name);
        }
    }

    @Override
    public List<SpecParamDTO> findparam(Long id, boolean searching) {
        SpuDetail spuDetail = spuDetailService.getById(id);
        Map<Long, Object> map = JsonUtils.toMap(spuDetail.getSpecification(), Long.class, Object.class);
        Spu spu = getById(id);
        List<SpecParamDTO> paramDTOS = specParamService.querybybrandid(null, spu.getCid3(), searching);
        for (SpecParamDTO paramDTO : paramDTOS) {
            paramDTO.setValue(map.get(paramDTO.getId()));
        }
        return paramDTOS;
    }
}